<?php

require_once('PHPDao/templates/class/dao/sql/Connection.php');
require_once('PHPDao/templates/class/dao/sql/ConnectionFactory.php');
require_once('PHPDao/templates/class/dao/sql/ConnectionProperty.php');
require_once('PHPDao/templates/class/dao/sql/QueryExecutor.php');
require_once('PHPDao/templates/class/dao/sql/DatabaseTransaction.php');
require_once('PHPDao/templates/class/dao/sql/SqlQuery.php');
require_once('PHPDao/templates/class/Template.php');

function generateDAO(){			
	$path = '../QFinance/php/';
	$sql = 'SHOW TABLES';
	$ret = QueryExecutor::execute(new SqlQuery($sql));
	init($path);
	generateDomainObjects($ret, $path);
	generateDAOObjects($ret, $path);
	generateDAOExtObjects($ret, $path);
	generateIDAOObjects($ret, $path);
	generateIDAOExtObjects($ret, $path);
	createDAOFactory($ret, $path);
}

function init($path){
	@mkdir($path);
	@mkdir($path . "dto"); destroy($path . "dto/");
	@mkdir($path . "dto/ext");
	@mkdir($path . "mysql"); destroy($path . "mysql/");
	@mkdir($path . "mysql/ext");
	@mkdir($path . "sql"); destroy($path . "sql/");
	@mkdir($path. "dao"); destroy($path . "dao/");
	@mkdir($path. "dao/ext");
	@mkdir($path . "core"); destroy($path . "core/");
	$baseFiles = array( 
		'PHPDao/templates/Connection.tpl' => $path . 'sql/Connection.php',
		'PHPDao/templates/ConnectionFactory.tpl' => $path . 'sql/ConnectionFactory.php',
		'PHPDao/templates/ConnectionProperty.tpl' => $path . 'sql/ConnectionProperty.php',
		'PHPDao/templates/QueryExecutor.tpl' => $path . 'sql/QueryExecutor.php',
		'PHPDao/templates/DatabaseTransaction.tpl' => $path . 'sql/DatabaseTransaction.php',
		'PHPDao/templates/SqlQuery.tpl' => $path . 'sql/SqlQuery.php',
		'PHPDao/templates/ArrayList.tpl' => $path . 'core/ArrayList.php'
	);
	
	foreach ($baseFiles as $source => $target) {
		$template = new Template( $source );		
		$template->write( $target);
	}
}

function destroy($dir) {
	echo "Cleaning $dir\n"; 
    $mydir = opendir($dir);
    while(false !== ($file = readdir($mydir))) {
        if($file != "." && $file != "..") {
            chmod($dir.$file, 0777);
            if(!is_dir($dir.$file))               
                unlink($dir.$file) or DIE("Couldn't delete $dir$file\n");
        }
    }
    closedir($mydir);
}

function doesTableContainPK($row){
	$row = getFields($row[0]);
	for($j=0;$j<count($row);$j++){
		if($row[$j][3]=='PRI'){
			return true;
		}
	}
	return false;
}

function createDAOFactory($ret, $path){
	$str ="\n";
	for($i=0;$i<count($ret);$i++){
		if(!doesTableContainPK($ret[$i])){
			continue;
		}
		$tableName = $ret[$i][0];
		$className = getClassName($tableName);
		$str .= "\t/**\n";
		$str .= "\t * @return ".$className."ExtDAO\n";
		$str .= "\t */\n";
		$str .= "\tpublic static function get".$className."DAO(){\n";
		$str .= "\t\treturn new ".$className."MySqlExtDAO();\n";
		$str .= "\t}\n\n";
	}
	$template = new Template('PHPDao/templates/DAOFactory.tpl');
	$template->set('content', $str);
	$template->write($path . 'dao/DAOFactory.php');
}

function generateDomainObjects($ret, $path){
	for($i=0;$i<count($ret);$i++){
		if(!doesTableContainPK($ret[$i])){
			continue;
		}
		$tableName = $ret[$i][0];
		$className = getClassName($tableName);
		if($className[strlen($className)-1]=='s'){
			$className = substr($className, 0, strlen($className)-1);
		}
		$template = new Template('PHPDao/templates/Domain.tpl');
		$template->set('domain_class_name', $className);
		$template->set('table_name', $tableName);
		$tab = getFields($tableName);
		$fields = "\r\n";
		for($j=0;$j<count($tab);$j++){
			$fields .= "\t\tvar $".getVarNameWithS($tab[$j][0]).";\n\r";
		}
		$template->set('variables', $fields);
		$template->set('date', date("Y-m-d H:i"));
		$template->write($path . 'dto/'.$className.'.php');
	}
}

function generateDAOExtObjects($ret, $path){
	for($i=0;$i<count($ret);$i++){
		if(!doesTableContainPK($ret[$i])){
			continue;
		}
		$tableName = $ret[$i][0];
		$className = getClassName($tableName).'MySqlExt';
		$classNameSup = getClassName($tableName).'MySql';
		$template = new Template('PHPDao/templates/DAOExt.tpl');
		$template->set('dao_class_sup_name', $classNameSup );
		$template->set('dao_class_imp_name', getClassName($tableName) );
		$template->set('dao_class_name', $className );
		$template->set('domain_class_name', getDTOName($tableName) );
		$template->set('idao_class_name', getClassName($tableName));
		$template->set('table_name', $tableName);
		$template->set('var_name', getVarName($tableName));
		$tab = getFields($tableName);
		$parameterSetter = "\n";
		$insertFields = "";
		$updateFields = "";
		$questionMarks = "";
		$readRow = "\n";
		$pk = '';
		$queryByField = '';
		$deleteByField = '';
		for($j=0;$j<count($tab);$j++){
			if($tab[$j][3]=='PRI'){
				$pk = $tab[$j][0];
			}else{
				$insertFields .= $tab[$j][0].", ";
				$updateFields .= $tab[$j][0]." = ?, ";
				$questionMarks .= "?, ";
				if(isColumnTypeNumber($tab[$j][1])){
					$parameterSetter .= "\t\t\$sqlQuery->setNumber($".getVarName($tableName)."->".getVarNameWithS($tab[$j][0]).");\n";
				}else{
					$parameterSetter .= "\t\t\$sqlQuery->set($".getVarName($tableName)."->".getVarNameWithS($tab[$j][0]).");\n";
				}
				$parameterSetter2 = '';
				if(isColumnTypeNumber($tab[$j][1])){
					$parameterSetter2 .= "Number";
				}
				$queryByField .= "	public function queryBy".getClassName($tab[$j][0])."(\$value){
		\$sql = 'SELECT * FROM ".$tableName." WHERE ".$tab[$j][0]." = ?';
		\$sqlQuery = new SqlQuery(\$sql);
		\$sqlQuery->set".$parameterSetter2."(\$value);
		return \$this->getList(\$sqlQuery);
	}\n\n";
				$deleteByField .= "	public function deleteBy".getClassName($tab[$j][0])."(\$value){
		\$sql = 'DELETE FROM ".$tableName." WHERE ".$tab[$j][0]." = ?';
		\$sqlQuery = new SqlQuery(\$sql);
		\$sqlQuery->set".$parameterSetter2."(\$value);
		return \$this->executeUpdate(\$sqlQuery);
	}\n\n";
			}
			$readRow .= "\t\t\$".getVarName($tableName)."->".getVarNameWithS($tab[$j][0])." = \$row['".$tab[$j][0]."'];\n";
		}
		if($pk==''){
			continue;
		}
		$insertFields = substr($insertFields,0, strlen($insertFields)-2);
		$updateFields = substr($updateFields,0, strlen($updateFields)-2);
		$questionMarks = substr($questionMarks,0, strlen($questionMarks)-2);
		$template->set('pk', $pk);
		$template->set('pk_php', getVarNameWithS($pk));		
		$template->set('insert_fields', $insertFields);
		$template->set('read_row', $readRow);
		$template->set('update_fields', $updateFields);
		$template->set('question_marks', $questionMarks);
		$template->set('parameter_setter',$parameterSetter);
		$template->set('read_row',$readRow);
		$template->set('date', date("Y-m-d H:i"));
		$template->set('queryByFieldFunctions',$queryByField);		
		$template->set('deleteByFieldFunctions',$deleteByField);
		$file = $path . 'mysql/ext/'.$className.'DAO.php';
		if(!file_exists($file)){
			$template->write($path . 'mysql/ext/'.$className.'DAO.php');
		}
	}
}


function generateDAOObjects($ret, $path){
	for($i=0;$i<count($ret);$i++){
		if(!doesTableContainPK($ret[$i])){
			continue;
		}
		$tableName = $ret[$i][0];
		$className = getClassName($tableName).'MySql';

		$tab = getFields($tableName);
		$parameterSetter = "\n";
		$insertFields = "";
		$updateFields = "";
		$questionMarks = "";
		$readRow = "\n";
		$pk = '';
		$pks = array();
		$queryByField = '';
		$deleteByField = '';
		$pk_type='';
		for($j=0;$j<count($tab);$j++){
			if($tab[$j][3]=='PRI'){
				$pk = $tab[$j][0];
				$c = count($pks);
				$pks[$c] = $tab[$j][0];
				$pk_type = $tab[$j][1];
			}else{
				$insertFields .= $tab[$j][0].", ";
				$updateFields .= $tab[$j][0]." = ?, ";
				$questionMarks .= "?, ";
				if(isColumnTypeNumber($tab[$j][1])){
					$parameterSetter .= "\t\t\$sqlQuery->setNumber($".getVarName($tableName)."->".getVarNameWithS($tab[$j][0]).");\n";
				}else{
					$parameterSetter .= "\t\t\$sqlQuery->set($".getVarName($tableName)."->".getVarNameWithS($tab[$j][0]).");\n";
				}
				$parameterSetter2 = '';
				if(isColumnTypeNumber($tab[$j][1])){
					$parameterSetter2 .= "Number";
				}
				$queryByField .= "	public function queryBy".getClassName($tab[$j][0])."(\$value){
		\$sql = 'SELECT * FROM ".$tableName." WHERE ".$tab[$j][0]." = ?';
		\$sqlQuery = new SqlQuery(\$sql);
		\$sqlQuery->set".$parameterSetter2."(\$value);
		return \$this->getList(\$sqlQuery);
	}\n\n";
				$deleteByField .= "	public function deleteBy".getClassName($tab[$j][0])."(\$value){
		\$sql = 'DELETE FROM ".$tableName." WHERE ".$tab[$j][0]." = ?';
		\$sqlQuery = new SqlQuery(\$sql);
		\$sqlQuery->set".$parameterSetter2."(\$value);
		return \$this->executeUpdate(\$sqlQuery);
	}\n\n";
			}
			$readRow .= "\t\t\$".getVarName($tableName)."->".getVarNameWithS($tab[$j][0])." = \$row['".$tab[$j][0]."'];\n";
		}
		if($pk==''){
			continue;
		}
		if(count($pks)==1){
			$template = new Template('PHPDao/templates/DAO.tpl');
			//echo '$pk_type ' .$pk_type . chr(13) . chr(10);
			if(isColumnTypeNumber($pk_type)){
				$template->set('pk_number', 'Number');
			}else{
				$template->set('pk_number', '');
			}
		}else{			
			$template = new Template('PHPDao/templates/DAO_with_complex_pk.tpl');
		}
		$template->set('dao_class_name', $className );
		$template->set('domain_class_name', getDTOName($tableName) );
		$template->set('idao_class_name', getClassName($tableName));
		$template->set('table_name', $tableName);
		$template->set('var_name', getVarName($tableName));
		
		$insertFields = substr($insertFields,0, strlen($insertFields)-2);
		$updateFields = substr($updateFields,0, strlen($updateFields)-2);
		$questionMarks = substr($questionMarks,0, strlen($questionMarks)-2);
		$template->set('pk', $pk);
		$s = '';
		$s2 = '';
		$s3 = '';
		$s4 = '';
		$insertFields2 = $insertFields;
		$questionMarks2 = $questionMarks;
		for($z=0;$z<count($pks);$z++){
			$questionMarks2.=', ?';			
			if($z>0){
				$s.=', ';								
				$s2.=' AND ';
				$s3.= "\t\t";
			}			
			$insertFields2.=', '.$pks[$z];
			$s .= '$'.getVarNameWithS($pks[$z]);
			$s2 .= $pks[$z].' = ? ';
			$s3 .= '$sqlQuery->setNumber($'.getVarNameWithS($pks[$z]).');';			
			$s3 .= "\n";
			$s4 .= "\n\t\t";
			$s4 .= '$sqlQuery->setNumber($'.getVarName($tableName).'->'.getVarNameWithS($pks[$z]).');';
			$s4 .= "\n";
		}
		if($s[0]==',')$s = substr($s,1);
		if($questionMarks2[0]==',')$questionMarks2= substr($questionMarks2,1);
		if($insertFields2[0]==',')$insertFields2= substr($insertFields2,1);
		$template->set('question_marks2', $questionMarks2);
		$template->set('insert_fields2', $insertFields2);
		$template->set('pk_set_update', $s4);
		$template->set('pk_set', $s3);		
		$template->set('pk_where', $s2);
		$template->set('pks', $s);
		$template->set('pk_php', getVarNameWithS($pk));		
		$template->set('insert_fields', $insertFields);
		$template->set('read_row', $readRow);
		$template->set('update_fields', $updateFields);
		$template->set('question_marks', $questionMarks);
		$template->set('parameter_setter',$parameterSetter);
		$template->set('read_row',$readRow);
		$template->set('date', date("Y-m-d H:i"));
		$template->set('queryByFieldFunctions',$queryByField);		
		$template->set('deleteByFieldFunctions',$deleteByField);

		$template->write( $path . 'mysql/'.$className.'DAO.php');
	}
}

function isColumnTypeNumber($columnType){
	//echo $columnType . chr(13) . chr(10);
	if(strtolower(substr($columnType,0,3))=='int' || strtolower(substr($columnType,0,7))=='tinyint'){
		return true;
	}
	return false;
}

function generateIDAOObjects($ret, $path){
	for($i=0;$i<count($ret);$i++){
		if(!doesTableContainPK($ret[$i])){
			continue;
		}
		$tableName = $ret[$i][0];
		$className = getClassName($tableName);
		$tab = getFields($tableName);
		$parameterSetter = "\n";
		$insertFields = "";
		$updateFields = "";
		$questionMarks = "";
		$readRow = "\n";
		$pk = '';
		$pks = array();
		$queryByField = '';
		$deleteByField = '';
		for($j=0;$j<count($tab);$j++){
			if($tab[$j][3]=='PRI'){
				$pk = $tab[$j][0];
				$c = count($pks);
				$pks[$c] = $tab[$j][0];
			}else{
				$insertFields .= $tab[$j][0].", ";
				$updateFields .= $tab[$j][0]." = ?, ";
				$questionMarks .= "?, ";
				if(isColumnTypeNumber($tab[$j][1])){
					$parameterSetter .= "\t\t\$sqlQuery->setNumber($".getVarName($tableName)."->".getVarNameWithS($tab[$j][0]).");\n";
				}else{
					$parameterSetter .= "\t\t".'$sqlQuery->set($'.getVarName($tab[$j][0]).');'."\n";
				}
				$queryByField .= "\tpublic function queryBy".getClassName($tab[$j][0])."(\$value);\n\n";
				$deleteByField .= "\tpublic function deleteBy".getClassName($tab[$j][0])."(\$value);\n\n";
			}
			$readRow .= "\t\t\$".getVarName($tableName)."->".getVarNameWithS($tab[$j][0])." = \$row['".$tab[$j][0]."'];\n";
		}
		if($pk==''){
			continue;
		}
		
		if(count($pks)==1){
			$template = new Template('PHPDao/templates/IDAO.tpl');
		}else{			
			$template = new Template('PHPDao/templates/IDAO_with_complex_pk.tpl');
		}
		
		$template->set('dao_class_name', $className );
		$template->set('table_name', $tableName);
		$template->set('var_name', getVarName($tableName));
		
		$s = '';
		$s2 = '';
		$s3 = '';
		$s4 = '';
		$insertFields2 = $insertFields;
		$questionMarks2 = $questionMarks;
		for($z=0;$z<count($pks);$z++){
			$questionMarks2.=', ?';			
			if($z>0){
				$s.=', ';								
				$s2.=' AND ';
				$s3.= "\t\t";
			}			
			$insertFields2.=', '.getVarNameWithS($pks[$z]);
			$s .= '$'.getVarNameWithS($pks[$z]);
			$s2 .= getVarNameWithS($pks[$z]).' = ? ';
			$s3 .= '$sqlQuery->setNumber('.getVarName($pks[$z]).');';			
			$s3 .= "\n";
			$s4 .= "\n\t\t";
			$s4 .= '$sqlQuery->setNumber($'.getVarName($tableName).'->'.getVarNameWithS($pks[$z]).');';
			$s4 .= "\n";
		}
		$template->set('question_marks2', $questionMarks2);
		$template->set('insert_fields2', $insertFields2);
		$template->set('pk_set_update', $s4);
		$template->set('pk_set', $s3);		
		$template->set('pk_where', $s2);
		$template->set('pks', $s);
		
		$insertFields = substr($insertFields,0, strlen($insertFields)-2);
		$updateFields = substr($updateFields,0, strlen($updateFields)-2);
		$questionMarks = substr($questionMarks,0, strlen($questionMarks)-2);
		$template->set('pk', $pk);
		$template->set('insert_fields', $insertFields);
		$template->set('read_row', $readRow);
		$template->set('update_fields', $updateFields);
		$template->set('question_marks', $questionMarks);
		$template->set('parameter_setter',$parameterSetter);
		$template->set('read_row',$readRow);
		$template->set('date', date("Y-m-d H:i"));
		$template->set('queryByFieldFunctions',$queryByField);
		$template->set('deleteByFieldFunctions',$deleteByField);
		$template->write( $path . 'dao/'.$className.'DAO.php');
	}
}

function generateIDAOExtObjects($ret, $path){
	for($i=0;$i<count($ret);$i++){
		if(!doesTableContainPK($ret[$i])){
			continue;
		}
		$tableName = $ret[$i][0];
		$className = getClassName($tableName) . "Ext";
		$tab = getFields($tableName);
		$parameterSetter = "\n";
		$insertFields = "";
		$updateFields = "";
		$questionMarks = "";
		$readRow = "\n";
		$pk = '';
		$pks = array();
		$queryByField = '';
		$deleteByField = '';
		for($j=0;$j<count($tab);$j++){
			if($tab[$j][3]=='PRI'){
				$pk = $tab[$j][0];
				$c = count($pks);
				$pks[$c] = $tab[$j][0];
			}else{
				$insertFields .= $tab[$j][0].", ";
				$updateFields .= $tab[$j][0]." = ?, ";
				$questionMarks .= "?, ";
				if(isColumnTypeNumber($tab[$j][1])){
					$parameterSetter .= "\t\t\$sqlQuery->setNumber($".getVarName($tableName)."->".getVarNameWithS($tab[$j][0]).");\n";
				}else{
					$parameterSetter .= "\t\t".'$sqlQuery->set($'.getVarName($tab[$j][0]).');'."\n";
				}
				$queryByField .= "\tpublic function queryBy".getClassName($tab[$j][0])."(\$value);\n\n";
				$deleteByField .= "\tpublic function deleteBy".getClassName($tab[$j][0])."(\$value);\n\n";
			}
			$readRow .= "\t\t\$".getVarName($tableName)."->".getVarNameWithS($tab[$j][0])." = \$row['".$tab[$j][0]."'];\n";
		}
		if($pk==''){
			continue;
		}
		
		if(count($pks)==1){
			$template = new Template('PHPDao/templates/IDAOExt.tpl');
		}else{			
			$template = new Template('PHPDao/templates/IDAOExt_with_complex_pk.tpl');
		}
		
		$template->set('dao_class_name', $className );
		$template->set('dao_class_sup_name', getClassName($tableName) );
		$template->set('table_name', $tableName);
		$template->set('var_name', getVarName($tableName));
		
		$s = '';
		$s2 = '';
		$s3 = '';
		$s4 = '';
		$insertFields2 = $insertFields;
		$questionMarks2 = $questionMarks;
		for($z=0;$z<count($pks);$z++){
			$questionMarks2.=', ?';			
			if($z>0){
				$s.=', ';								
				$s2.=' AND ';
				$s3.= "\t\t";
			}			
			$insertFields2.=', '.getVarNameWithS($pks[$z]);
			$s .= '$'.getVarNameWithS($pks[$z]);
			$s2 .= getVarNameWithS($pks[$z]).' = ? ';
			$s3 .= '$sqlQuery->setNumber('.getVarName($pks[$z]).');';			
			$s3 .= "\n";
			$s4 .= "\n\t\t";
			$s4 .= '$sqlQuery->setNumber($'.getVarName($tableName).'->'.getVarNameWithS($pks[$z]).');';
			$s4 .= "\n";
		}
		$template->set('question_marks2', $questionMarks2);
		$template->set('insert_fields2', $insertFields2);
		$template->set('pk_set_update', $s4);
		$template->set('pk_set', $s3);		
		$template->set('pk_where', $s2);
		$template->set('pks', $s);
		
		$insertFields = substr($insertFields,0, strlen($insertFields)-2);
		$updateFields = substr($updateFields,0, strlen($updateFields)-2);
		$questionMarks = substr($questionMarks,0, strlen($questionMarks)-2);
		$template->set('pk', $pk);
		$template->set('insert_fields', $insertFields);
		$template->set('read_row', $readRow);
		$template->set('update_fields', $updateFields);
		$template->set('question_marks', $questionMarks);
		$template->set('parameter_setter',$parameterSetter);
		$template->set('read_row',$readRow);
		$template->set('date', date("Y-m-d H:i"));
		$template->set('queryByFieldFunctions',$queryByField);
		$template->set('deleteByFieldFunctions',$deleteByField);
		$file = $path . 'dao/ext/'.$className.'DAO.php';
		if(!file_exists($file)){
			$template->write($file);
		}
	}
}

function getFields($table){
	$sql = 'DESC '.$table;
	return QueryExecutor::execute(new SqlQuery($sql));
}


function getClassName($tableName){
	$tableName = strtoupper($tableName[0]).substr($tableName,1);
	for($i=0;$i<strlen($tableName);$i++){
		if($tableName[$i]=='_'){
			$tableName = substr($tableName, 0, $i).strtoupper($tableName[$i+1]).substr($tableName, $i+2);
		}
	}
	return $tableName;
}

function getDTOName($tableName){
	$name = getClassName($tableName);
	if($name[strlen($name)-1]=='s'){
		$name = substr($name, 0, strlen($name)-1);
	}
	return $name;
}

function getVarName($tableName){
	$tableName = strtolower($tableName[0]).substr($tableName,1);
	for($i=0;$i<strlen($tableName);$i++){
		if($tableName[$i]=='_'){
			$tableName = substr($tableName, 0, $i).strtoupper($tableName[$i+1]).substr($tableName, $i+2);
		}
	}
	if($tableName[strlen($tableName)-1]=='s'){
		$tableName = substr($tableName, 0, strlen($tableName)-1);
	}
	return $tableName;
}


function getVarNameWithS($tableName){
	$tableName = strtolower($tableName[0]).substr($tableName,1);
	for($i=0;$i<strlen($tableName);$i++){
		if($tableName[$i]=='_'){
			$tableName = substr($tableName, 0, $i).strtoupper($tableName[$i+1]).substr($tableName, $i+2);
		}
	}
	return $tableName;
}
?>